<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文档生成任务列表</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/inter-ui@3.19.3/inter.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    fontFamily: {
                        sans: ['Inter', 'sans-serif'],
                    },
                    colors: {
                        primary: {
                            50: '#eef2ff',
                            100: '#e0e7ff',
                            200: '#c7d2fe',
                            300: '#a5b4fc',
                            400: '#818cf8',
                            500: '#6366f1',
                            600: '#4f46e5',
                            700: '#4338ca',
                            800: '#3730a3',
                            900: '#312e81',
                        }
                    }
                }
            }
        }
    </script>
</head>
<body class="bg-gray-50 font-sans min-h-screen flex flex-col">
    <!-- 加载中遮罩 -->
    <div id="loadingOverlay"
         class="fixed inset-0 bg-white bg-opacity-80 z-50 flex items-center justify-center hidden">
        <div class="text-center">
            <div class="inline-block animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-primary-600"></div>
            <p class="mt-2 text-primary-800 font-medium" id="loadingText">正在处理，请稍候...</p>
        </div>
    </div>

    <!-- 顶部导航 -->
    <nav class="bg-white shadow-sm">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
            <div class="flex justify-between h-16">
                <div class="flex items-center">
                    <div class="flex-shrink-0 flex items-center">
                        <svg class="h-8 w-8 text-primary-600" xmlns="http://www.w3.org/2000/svg" fill="none"
                             viewBox="0 0 24 24" stroke="currentColor">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                  d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
                        </svg>
                        <span class="ml-2 text-xl font-semibold text-gray-900">文档智能生成平台</span>
                    </div>
                </div>
                <div class="flex items-center">
                    <a href="/docs"
                       class="ml-4 px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-primary-500">
                        <i class="fas fa-home mr-1"></i> 首页
                    </a>
                    <a href="/tasks/list"
                       class="ml-4 px-3 py-2 rounded-md text-sm font-medium text-primary-700 bg-primary-50 hover:text-primary-800 hover:bg-primary-100 focus:outline-none focus:ring-2 focus:ring-primary-500">
                        <i class="fas fa-tasks mr-1"></i> 任务管理
                    </a>
                </div>
            </div>
        </div>
    </nav>

    <!-- 主容器 -->
    <main class="flex-grow max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8 py-10">
        <div class="bg-white shadow-sm sm:rounded-lg overflow-hidden">
            <div class="px-4 py-5 sm:p-6">
                <div class="flex items-center mb-4">
                    <div class="flex-shrink-0 h-10 w-10 rounded-full bg-primary-100 flex items-center justify-center">
                        <i class="fas fa-tasks text-primary-600"></i>
                    </div>
                    <h3 class="ml-3 text-lg font-medium text-gray-900">文档生成任务列表</h3>
                </div>

                <!-- 搜索和筛选 -->
                <div class="mt-4 mb-6">
                    <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
                        <div class="flex relative">
                            <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                                <i class="fas fa-search text-gray-400"></i>
                            </div>
                            <input type="text" id="searchInput"
                                   class="focus:ring-primary-500 focus:border-primary-500 block w-full pl-10 pr-12 sm:text-sm border-gray-300 rounded-md"
                                   placeholder="搜索任务ID">
                        </div>

                        <div class="flex items-center col-span-1">
                            <label for="statusFilter" class="mr-2 text-gray-700 text-sm">状态:</label>
                            <select id="statusFilter"
                                    class="focus:ring-primary-500 focus:border-primary-500 h-full py-0 pl-2 pr-7 border-gray-300 bg-white text-gray-500 sm:text-sm rounded-md">
                                <option value="">全部</option>
                                <option value="PENDING">等待中</option>
                                <option value="PROCESSING">处理中</option>
                                <option value="COMPLETED">已完成</option>
                                <option value="FAILED">失败</option>
                            </select>
                        </div>

                        <div class="flex justify-end col-span-1">
                            <button type="button" id="refreshBtn"
                                    class="inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
                                <i class="fas fa-sync-alt mr-2"></i> 刷新
                            </button>
                            <a href="/docs"
                               class="ml-3 inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
                                <i class="fas fa-file-medical mr-2"></i> 新建任务
                            </a>
                        </div>
                    </div>
                </div>

                <!-- 任务列表 -->
                <div class="mt-6">
                    <div class="overflow-x-auto">
                        <table class="min-w-full divide-y divide-gray-200">
                            <thead class="bg-gray-50">
                                <tr>
                                    <th scope="col"
                                        class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                        任务ID
                                    </th>
                                    <th scope="col"
                                        class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                        状态
                                    </th>
                                    <th scope="col"
                                        class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                        进度
                                    </th>
                                    <th scope="col"
                                        class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                        创建时间
                                    </th>
                                    <th scope="col"
                                        class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                                        完成时间
                                    </th>
                                    <th scope="col"
                                        class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">
                                        操作
                                    </th>
                                </tr>
                            </thead>
                            <tbody id="taskTableBody" class="bg-white divide-y divide-gray-200">
                                <!-- 任务列表将动态生成 -->
                            </tbody>
                        </table>
                    </div>
                    
                    <!-- 空状态 -->
                    <div id="emptyState" class="hidden my-12 flex flex-col items-center justify-center text-center">
                        <svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24"
                             stroke="currentColor" aria-hidden="true">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                  d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
                        </svg>
                        <h3 class="mt-2 text-sm font-medium text-gray-900">没有找到任务</h3>
                        <p class="mt-1 text-sm text-gray-500">您还未创建任何文档生成任务，或没有符合搜索条件的任务。</p>
                    </div>
                </div>

                <!-- 分页 -->
                <div id="pagination" class="mt-4 flex items-center justify-between border-t border-gray-200 px-4 py-3 sm:px-6">
                    <div class="flex-1 flex justify-between sm:hidden">
                        <button id="prevPageBtnMobile" class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
                            上一页
                        </button>
                        <button id="nextPageBtnMobile" class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
                            下一页
                        </button>
                    </div>
                    <div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
                        <div>
                            <p class="text-sm text-gray-700">
                                显示第 <span id="startRecord" class="font-medium">0</span> 至 <span id="endRecord" class="font-medium">0</span> 条，共 <span id="totalRecords" class="font-medium">0</span> 条记录
                            </p>
                        </div>
                        <div>
                            <nav class="relative z-0 inline-flex rounded-md shadow-sm -space-x-px" aria-label="Pagination">
                                <button id="prevPageBtn" class="relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50">
                                    <span class="sr-only">上一页</span>
                                    <i class="fas fa-chevron-left"></i>
                                </button>
                                <div id="pageNumbers" class="relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700">
                                    <!-- 页码将动态生成 -->
                                </div>
                                <button id="nextPageBtn" class="relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50">
                                    <span class="sr-only">下一页</span>
                                    <i class="fas fa-chevron-right"></i>
                                </button>
                            </nav>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </main>

    <!-- 页脚 -->
    <footer class="bg-white border-t border-gray-200 mt-auto">
        <div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
            <p class="text-center text-sm text-gray-500">© 2025 文档智能生成平台 | 版本 2.0</p>
        </div>
    </footer>

    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
        // 页面加载完成后执行
        document.addEventListener('DOMContentLoaded', function () {
            // 初始查询参数
            const queryParams = {
                pageNum: 1,
                pageSize: 10,
                taskId: '',
                status: ''
            };
            
            // DOM元素
            const loadingOverlay = document.getElementById('loadingOverlay');
            const loadingText = document.getElementById('loadingText');
            const searchInput = document.getElementById('searchInput');
            const statusFilter = document.getElementById('statusFilter');
            const refreshBtn = document.getElementById('refreshBtn');
            const taskTableBody = document.getElementById('taskTableBody');
            const emptyState = document.getElementById('emptyState');
            const pagination = document.getElementById('pagination');
            const prevPageBtn = document.getElementById('prevPageBtn');
            const nextPageBtn = document.getElementById('nextPageBtn');
            const prevPageBtnMobile = document.getElementById('prevPageBtnMobile');
            const nextPageBtnMobile = document.getElementById('nextPageBtnMobile');
            const pageNumbers = document.getElementById('pageNumbers');
            const startRecord = document.getElementById('startRecord');
            const endRecord = document.getElementById('endRecord');
            const totalRecords = document.getElementById('totalRecords');
            
            // 显示加载中
            function showLoading(text) {
                loadingText.innerText = text || '正在加载，请稍候...';
                loadingOverlay.classList.remove('hidden');
            }
            
            // 隐藏加载中
            function hideLoading() {
                loadingOverlay.classList.add('hidden');
            }
            
            // 显示通知
            function showNotification(message, type = 'success') {
                // 创建通知元素
                const notification = document.createElement('div');
                let bgColor, textColor, iconClass;
                if (type === 'success') {
                    bgColor = 'bg-green-50';
                    textColor = 'text-green-800';
                    iconClass = 'fa-check-circle text-green-400';
                } else if (type === 'error') {
                    bgColor = 'bg-red-50';
                    textColor = 'text-red-800';
                    iconClass = 'fa-exclamation-circle text-red-400';
                } else if (type === 'warning') {
                    bgColor = 'bg-yellow-50';
                    textColor = 'text-yellow-800';
                    iconClass = 'fa-exclamation-triangle text-yellow-400';
                } else {
                    bgColor = 'bg-blue-50';
                    textColor = 'text-blue-800';
                    iconClass = 'fa-info-circle text-blue-400';
                }
                notification.className = `fixed top-4 right-4 w-80 ${bgColor} border-l-4 border-${type === 'success' ? 'green' : type === 'error' ? 'red' : type === 'warning' ? 'yellow' : 'blue'}-400 p-4 shadow-md rounded transform transition-all duration-300 ease-in-out z-50`;
                notification.innerHTML = `
                    <div class="flex">
                        <div class="flex-shrink-0">
                            <i class="fas ${iconClass}"></i>
                        </div>
                        <div class="ml-3">
                            <p class="text-sm font-medium ${textColor}">${message}</p>
                        </div>
                        <div class="ml-auto pl-3">
                            <div class="-mx-1.5 -my-1.5">
                                <button type="button" class="inline-flex ${bgColor} rounded-md p-1.5 ${textColor} hover:bg-${type === 'success' ? 'green' : type === 'error' ? 'red' : type === 'warning' ? 'yellow' : 'blue'}-100 focus:outline-none">
                                    <span class="sr-only">关闭</span>
                                    <i class="fas fa-times"></i>
                                </button>
                            </div>
                        </div>
                    </div>
                `;
                // 添加到页面
                document.body.appendChild(notification);
                // 点击关闭按钮
                notification.querySelector('button').addEventListener('click', () => {
                    notification.classList.add('opacity-0');
                    setTimeout(() => {
                        document.body.removeChild(notification);
                    }, 300);
                });
                // 自动关闭
                setTimeout(() => {
                    notification.classList.add('opacity-0');
                    setTimeout(() => {
                        if (document.body.contains(notification)) {
                            document.body.removeChild(notification);
                        }
                    }, 300);
                }, 5000);
            }
            
            // 格式化时间
            function formatDateTime(dateTimeStr) {
                if (!dateTimeStr) return '-';
                const date = new Date(dateTimeStr);
                return date.toLocaleString('zh-CN', { 
                    year: 'numeric', 
                    month: '2-digit', 
                    day: '2-digit',
                    hour: '2-digit',
                    minute: '2-digit',
                    second: '2-digit'
                });
            }
            
            // 获取状态标签
            function getStatusBadge(status) {
                let badgeClass, icon, text;
                switch (status) {
                    case 'PENDING':
                        badgeClass = 'bg-yellow-100 text-yellow-800';
                        icon = 'fa-clock';
                        text = '等待中';
                        break;
                    case 'PROCESSING':
                        badgeClass = 'bg-blue-100 text-blue-800';
                        icon = 'fa-spinner fa-spin';
                        text = '处理中';
                        break;
                    case 'COMPLETED':
                        badgeClass = 'bg-green-100 text-green-800';
                        icon = 'fa-check';
                        text = '已完成';
                        break;
                    case 'FAILED':
                        badgeClass = 'bg-red-100 text-red-800';
                        icon = 'fa-exclamation-triangle';
                        text = '失败';
                        break;
                    default:
                        badgeClass = 'bg-gray-100 text-gray-800';
                        icon = 'fa-question';
                        text = '未知';
                }
                
                return `<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${badgeClass}">
                    <i class="fas ${icon} mr-1"></i> ${text}
                </span>`;
            }
            
            // 获取进度条
            function getProgressBar(progress, status) {
                // 根据状态设置颜色
                let barColor;
                switch (status) {
                    case 'PROCESSING':
                        barColor = 'bg-blue-500';
                        break;
                    case 'COMPLETED':
                        barColor = 'bg-green-500';
                        break;
                    case 'FAILED':
                        barColor = 'bg-red-500';
                        break;
                    default:
                        barColor = 'bg-gray-500';
                }
                
                return `<div class="w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-700">
                    <div class="${barColor} h-2.5 rounded-full" style="width: ${progress}%"></div>
                </div>
                <div class="text-xs mt-1 text-gray-500 text-right">${progress}%</div>`;
            }
            
            // 查询任务列表
            function fetchTasks() {
                showLoading('正在加载任务列表...');
                
                // 添加调试日志
                console.log('查询参数:', JSON.stringify(queryParams));
                
                axios.post('/tasks/page', queryParams)
                    .then(response => {
                        hideLoading();
                        
                        // 添加调试日志
                        console.log('响应数据:', response.data);
                        
                        if (response.data.success) {
                            const pageResult = response.data.data;
                            renderTaskList(pageResult);
                        } else {
                            showNotification(response.data.message || '加载任务列表失败', 'error');
                        }
                    })
                    .catch(error => {
                        hideLoading();
                        console.error('查询任务列表出错:', error);
                        showNotification('加载任务列表失败: ' + (error.response?.data || error.message), 'error');
                    });
            }
            
            // 渲染任务列表
            function renderTaskList(pageResult) {
                const { list, pageNum, pageSize, total, pages } = pageResult;
                
                // 清空表格
                taskTableBody.innerHTML = '';
                
                if (!list || list.length === 0) {
                    // 显示空状态
                    emptyState.classList.remove('hidden');
                    pagination.classList.add('hidden');
                    return;
                }
                
                // 隐藏空状态，显示分页
                emptyState.classList.add('hidden');
                pagination.classList.remove('hidden');
                
                // 渲染任务列表
                list.forEach(task => {
                    const row = document.createElement('tr');
                    row.innerHTML = `
                        <td class="px-6 py-4 whitespace-nowrap">
                            <div class="text-sm text-gray-900">${task.taskId}</div>
                        </td>
                        <td class="px-6 py-4 whitespace-nowrap">
                            ${getStatusBadge(task.status)}
                        </td>
                        <td class="px-6 py-4 whitespace-nowrap">
                            ${getProgressBar(task.progress, task.status)}
                        </td>
                        <td class="px-6 py-4 whitespace-nowrap">
                            <div class="text-sm text-gray-900">${formatDateTime(task.createTime)}</div>
                        </td>
                        <td class="px-6 py-4 whitespace-nowrap">
                            <div class="text-sm text-gray-900">${formatDateTime(task.completeTime)}</div>
                        </td>
                        <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
                            <a href="/tasks/detail/${task.taskId}" class="text-primary-600 hover:text-primary-900">
                                <i class="fas fa-eye mr-1"></i> 查看
                            </a>
                        </td>
                    `;
                    taskTableBody.appendChild(row);
                });
                
                // 更新分页信息
                updatePagination(pageNum, pageSize, total, pages);
            }
            
            // 更新分页组件
            function updatePagination(pageNum, pageSize, total, pages) {
                // 计算开始和结束记录
                const start = (pageNum - 1) * pageSize + 1;
                const end = Math.min(pageNum * pageSize, total);
                
                // 更新记录信息
                startRecord.textContent = start;
                endRecord.textContent = end;
                totalRecords.textContent = total;
                
                // 禁用或启用上一页/下一页按钮
                prevPageBtn.disabled = pageNum <= 1;
                nextPageBtn.disabled = pageNum >= pages;
                prevPageBtnMobile.disabled = pageNum <= 1;
                nextPageBtnMobile.disabled = pageNum >= pages;
                
                if (prevPageBtn.disabled) {
                    prevPageBtn.classList.add('opacity-50', 'cursor-not-allowed');
                } else {
                    prevPageBtn.classList.remove('opacity-50', 'cursor-not-allowed');
                }
                
                if (nextPageBtn.disabled) {
                    nextPageBtn.classList.add('opacity-50', 'cursor-not-allowed');
                } else {
                    nextPageBtn.classList.remove('opacity-50', 'cursor-not-allowed');
                }
                
                // 渲染页码
                pageNumbers.innerHTML = `${pageNum} / ${pages}`;
            }
            
            // 绑定事件处理程序
            searchInput.addEventListener('input', function() {
                queryParams.taskId = this.value.trim();
                queryParams.pageNum = 1; // 重置页码
                fetchTasks();
            });
            
            statusFilter.addEventListener('change', function() {
                queryParams.status = this.value;
                queryParams.pageNum = 1; // 重置页码
                fetchTasks();
            });
            
            refreshBtn.addEventListener('click', function() {
                fetchTasks();
            });
            
            prevPageBtn.addEventListener('click', function() {
                if (queryParams.pageNum > 1) {
                    queryParams.pageNum--;
                    fetchTasks();
                }
            });
            
            nextPageBtn.addEventListener('click', function() {
                queryParams.pageNum++;
                fetchTasks();
            });
            
            prevPageBtnMobile.addEventListener('click', function() {
                if (queryParams.pageNum > 1) {
                    queryParams.pageNum--;
                    fetchTasks();
                }
            });
            
            nextPageBtnMobile.addEventListener('click', function() {
                queryParams.pageNum++;
                fetchTasks();
            });
            
            // 初始加载任务列表
            fetchTasks();
            
            // 轮询任务列表中的处理中任务
            function pollProcessingTasks() {
                // 只有在页面可见时才刷新
                if (document.visibilityState !== 'visible') {
                    return;
                }
                
                // 查找处理中的任务
                const processingTasks = Array.from(taskTableBody.querySelectorAll('tr')).filter(row => {
                    const statusCell = row.cells[1];
                    return statusCell.textContent.includes('处理中');
                });
                
                if (processingTasks.length === 0) {
                    return;  // 没有处理中的任务，不刷新
                }
                
                // 静默刷新，不显示加载提示
                axios.post('/tasks/page', queryParams)
                    .then(response => {
                        if (response.data.success) {
                            const pageResult = response.data.data;
                            renderTaskList(pageResult);
                        } else {
                            console.error('静默刷新任务列表失败:', response.data.message);
                            // 静默失败，不显示错误提示
                        }
                    })
                    .catch(error => {
                        console.error('静默刷新任务列表出错:', error);
                        // 静默失败，不显示错误提示
                    });
            }
            
            // 每隔5秒自动刷新处理中的任务
            setInterval(pollProcessingTasks, 5000);
        });
    </script>
</body>
</html> 